﻿using System;
using System.Windows;
using Gwn.Library.MvpVm.Configuration;
using Gwn.Library.MvpVm.Events;
using Gwn.Library.MvpVm.Extensions;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Logging;
using Microsoft.Practices.Unity;

namespace Gwn.Library.MvpVm.Base
{
    /// <summary>
    /// Common declarations
    /// </summary>
    public class ClassBase
    {
        /// <summary>
        /// Gets or sets the app config.
        /// </summary>
        /// <value>The app config.</value>
        [Dependency]
        public IAppConfig AppConfig { get; set; }

        /// <summary>
        /// Message and Type.FullName concatenated
        /// </summary>
        protected Func<string, ClassBase, string> MessageType = (m, t) => m + t.GetType().FullName;

        /// <summary>
        /// MessageBox
        /// </summary>
        public static Func<string, string, MessageBoxButton, MessageBoxResult> MessageBoxShow { get; set; }


        /// <summary>
        /// Gets or sets the ClassName.
        /// </summary>
        /// <value>The start date.</value>
        public string ClassName
        {
            get { return GetType().Name; }
        }

      


        private IUnityContainer _unityContainer;
        /// <summary>
        /// Gets or sets the Container.
        /// </summary>
        /// <value>The start date.</value>
        [Dependency]
        public IUnityContainer Container
        {
            get { return _unityContainer; }
            set
            {
                _unityContainer = value;
                ContainerPropertySet();
            }
        }

        /// <summary>
        /// Called by Container property setter when Container is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        private void ContainerPropertySet()
        {
            // Set static properties on classes that will
            // not be resolved (that require container)
            if (ValueConverterBase.Container == null)
                ValueConverterBase.Container = Container;

            HandleContainerPropertyWhenSet();
        }

        /// <summary>
        /// Called by ContainerPropertySet() when Container is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        protected virtual void HandleContainerPropertyWhenSet()
        {
            // Intended to be overridden
        }


        private IEventAggregator _eventAggregator;
        /// <summary>
        /// Gets or sets the EventAggregator.
        /// </summary>
        /// <value>The start date.</value>
        [Dependency]
        public IEventAggregator EventAggregator
        {
            get { return _eventAggregator; }
            set
            {
                _eventAggregator = value;
                EventAggregatorPropertySet();
            }
        }

        /// <summary>
        /// Called by EventAggregator property setter when EventAggregator is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        private void EventAggregatorPropertySet()
        {
            HandleEventAggregatorPropertyWhenSet();
        }

        /// <summary>
        /// Called by EventAggregatorPropertySet() when EventAggregator is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        protected virtual void HandleEventAggregatorPropertyWhenSet()
        {
            // Intended to be overridden
        }



        private Guid _uniqueId;
        /// <summary>
        /// Unique id for the BLL
        /// </summary>
        /// <value>The start date.</value>
        public Guid UniqueId
        {
            get { return _uniqueId; }
            set { _uniqueId = value; }
        }

        private ILoggerFacade _logger;
        /// <summary>
        /// Gets or sets the LoggerFacade.
        /// </summary>
        /// <value>The start date.</value>
        [Dependency]
        public ILoggerFacade Logger
        {
            get { return _logger; }
            set
            {
                _logger = value;
                LoggerFacadePropertySet();
            }
        }


        /// <summary>
        /// Called by LoggerFacade property setter when LoggerFacade is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        private void LoggerFacadePropertySet()
        {
            HandleLoggerFacadePropertyWhenSet();
        }

        /// <summary>
        /// Called by LoggerFacadePropertySet() when LoggerFacade is set by Unity container
        /// </summary>
        /// <value>The start date.</value>
        protected virtual void HandleLoggerFacadePropertyWhenSet()
        {
            // Intended to be overridden
        }


        /// <summary>
        /// Initializes a new instance of the <see cref="ClassBase"/> class.
        /// </summary>
        public ClassBase()
        {
            UniqueId = Guid.NewGuid();
        } 

        /// <summary>
        /// Subscribes to data event.
        /// </summary>
        /// <param name="callback">The callback.</param>
        protected void SubscribeToDataEvent(Action<ProcessEventArgs> callback)
        {
            EventAggregator.GetEvent<ProcessEvent>().Subscribe(callback);
        }


        /// <summary>
        /// Throws the exception.
        /// </summary>
        /// <typeparam name="TException">The type of the exception.</typeparam>
        /// <param name="message">The message.</param>
        public void ThrowException<TException>(string message)
            where TException : Exception
        {
            this.ThrowEx<TException>(message);
        }
        

    }
}
